home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 33 / Amiga Format AFCD33 (Issue 117, Dec 1998).iso / -seriously_amiga- / graphics / splitmpegppc / src / parsers.c < prev    next >
C/C++ Source or Header  |  1998-09-07  |  7KB  |  273 lines

  1.  
  2. /*
  3.  * Copyright (c) 1994 Michael Simmons.
  4.  * All rights reserved.
  5.  * 
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose, without fee, and without written agreement is
  8.  * hereby granted, provided that the above copyright notice and the following
  9.  * two paragraphs appear in all copies of this software.
  10.  * 
  11.  * IN NO EVENT SHALL MICHAEL SIMMONS BE LIABLE TO ANY PARTY FOR
  12.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  13.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF MICHAEL SIMMONS
  14.  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15.  * 
  16.  * THE MICHAEL SIMMONS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  17.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  18.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  19.  * ON AN "AS IS" BASIS, AND MICHAEL SIMMONS HAS NO OBLIGATION TO
  20.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  21.  *
  22.  * I can be contacted via 
  23.  * Email: michael@ecel.uwa.edu.au
  24.  * Post: P.O. Box 506, NEDLANDS WA 6009, AUSTRALIA
  25.  *
  26.  * Amigaversion by Tobias Seiler in 1997
  27.  * Email: tabs@blader.com
  28.  */
  29.  
  30. /*
  31.  * Routines to parse the different parts of a pack 
  32.  */
  33.  
  34. #include    "main.h"
  35.  
  36. #define check_marker                        \
  37. {                                           \
  38.     get_bits1(&data);                       \
  39.     if ( data != 1)                         \
  40.         return (err | ERR_INVALID_MARKER); \
  41. }
  42.  
  43. /*
  44.  * Parses the pack header
  45.  * 
  46.  */
  47.  
  48. int parse_pack_header(Pack_Header *pack_header)
  49. {
  50.     unsigned int data;
  51.     int err = ERR_PARSE_PACK_HDR;
  52.  
  53.     flush_bits(32);    /* Flush PACK_START_CODE */
  54.     
  55.     get_bits4(&data);
  56.     if( data != 2)
  57.         return (err | ERR_INVALID_BITS);
  58.     
  59.     /* Get System Clock Reference*/  
  60.     get_bits1(&data);
  61.     pack_header->SCR_hibit = data;
  62.     get_bits2(&data);
  63.     pack_header->SCR = data << 30;
  64.     check_marker;
  65.     get_bits15(&data);
  66.     pack_header->SCR |= data << 15;
  67.     check_marker;
  68.     get_bits15(&data);
  69.     pack_header->SCR |= data;
  70.     check_marker;
  71.     check_marker;
  72.     
  73.     /* Get Mux Rate */
  74.     get_bits22(&data);
  75.     pack_header->mux_rate = data;
  76.     check_marker;
  77.  
  78.     return NO_ERROR;
  79. }
  80.  
  81. /*
  82.  *    Parses the system header
  83.  */
  84.  
  85. int parse_system_header( System_Header *system_header)
  86. {
  87.     unsigned int data;
  88.     unsigned int stream_id;
  89.     int err = ERR_PARSE_SYSTEM_HDR;
  90.  
  91.     flush_bits(32);    /* flush SYSTEM_HEADER_START_CODE */
  92.  
  93.     /* extract system header information */
  94.     get_bits16(&data);
  95.     system_header->header_length = data;
  96.     check_marker;
  97.     get_bits22(&data);
  98.     system_header->rate_bound = data;
  99.     check_marker;
  100.     get_bits6(&data);
  101.     system_header->audio_bound = data;
  102.     get_bits1(&data);
  103.     system_header->fixed_flag = data;
  104.     get_bits1(&data);
  105.     system_header->CSPS_flag = data;
  106.     get_bits1(&data);
  107.     system_header->audio_lock_flag = data;
  108.     get_bits1(&data);
  109.     system_header->video_lock_flag = data;
  110.     check_marker;
  111.     get_bits5(&data);
  112.     system_header->video_bound = data;
  113.     get_bits8(&data);
  114.     system_header->reserved_byte = data;
  115.  
  116.     /* flag STD buffer bounds for each stream as invalid*/ 
  117.     for( stream_id=0; stream_id< MAX_NUM_STREAMS; stream_id++)
  118.         system_header->STD_flag[stream_id] = FALSE;
  119.  
  120.     while ( next_bits(1,1)){
  121.  
  122.         /* get stream number */
  123.         get_bits8(&data);
  124.         if( data < (RESERVED_STREAM & 0xff) || data > (RESERVED_DATA_STREAM_15 & 0xff))
  125.             return (err | ERR_INVALID_STREAM_NUM );
  126.         stream_id = data - (RESERVED_STREAM & 0xff);
  127.     
  128.         get_bits2(&data);
  129.         if( data != 3 )
  130.                return (err | ERR_INVALID_BITS);
  131.  
  132.          /* Extract the STD buffer bounds for stream stream_id and flag it as valid */ 
  133.         get_bits1(&data);
  134.         system_header->STD_scale_bound[stream_id] = data;
  135.         get_bits13(&data);
  136.         system_header->STD_size_bound[stream_id] = data;
  137.         system_header->STD_flag[stream_id] = TRUE;
  138.     }
  139.  
  140.     return NO_ERROR;
  141. }
  142.  
  143. /*
  144.  * Reads in a packet from the stream
  145.  * Updates the current stream info
  146.  * Create a buffer and put the packet data in it
  147. */
  148.  
  149. int parse_packet(Packet *packet)
  150. {
  151.     unsigned int    data = NULL;
  152.     unsigned int    byte_count;
  153.     int err = ERR_PARSE_SYSTEM_HDR;
  154.     int                i,stream_num;
  155.     char            *bptr;
  156.     get_bits24(&data);
  157.     get_bits8(&data);
  158.  
  159.     if( data < (RESERVED_STREAM & 0xff) || data > (RESERVED_DATA_STREAM_15 & 0xff))
  160.         return (err | ERR_INVALID_STREAM_NUM );
  161.  
  162.     packet->stream_id = data;
  163.  
  164.     stream_num = packet->stream_id - (RESERVED_STREAM & 0xff);
  165.     
  166.     get_bits16(&data);
  167.     packet->packet_length = data;
  168.  
  169.     byte_count =0;
  170.  
  171.     packet->STD_flag=packet->PTS_Flag=packet->DTS_Flag = FALSE;
  172.     
  173.     if( packet->stream_id != PRIVATE_STREAM_2 ){
  174.  
  175.         /* flush stuffing bytes */
  176.         while( next_bits(8,0xff)){
  177.             flush_bits(8);
  178.             byte_count++;
  179.         }
  180.     
  181.         if( next_bits(2,1)){
  182.             flush_bits(2);
  183.  
  184.             /* Get STD buffer size and flag it as present in packet*/
  185.             get_bits1(&data);
  186.             streamInfo[stream_num].STD_scale=data;
  187.             get_bits13(&data);
  188.             streamInfo[stream_num].STD_size=data;
  189.             packet->STD_flag=TRUE;
  190.             byte_count +=2;
  191.         }
  192.  
  193.         if( next_bits(4,2)){
  194.             flush_bits(4);
  195.  
  196.             /* Get presentation time stamp and flag it as present in packet*/
  197.             get_bits1(&data);
  198.             streamInfo[stream_num].PTS_hibit = data;
  199.             get_bits2(&data);
  200.             streamInfo[stream_num].PTS = data << 30;
  201.             check_marker;
  202.             get_bits15(&data);
  203.             streamInfo[stream_num].PTS |= data << 15;
  204.             check_marker;
  205.             get_bits15(&data);
  206.             streamInfo[stream_num].PTS |= data;
  207.             check_marker;
  208.             packet->PTS_Flag=TRUE;
  209.             byte_count +=5;
  210.             
  211.         }else if (next_bits(4,3)){
  212.             flush_bits(4);
  213.  
  214.             /* Get presentation time stamp and decoding time stamp */
  215.             /* and flag them as present in packet*/
  216.             get_bits1(&data);
  217.             streamInfo[stream_num].PTS_hibit = data;
  218.             get_bits2(&data);
  219.             streamInfo[stream_num].PTS = data << 30;
  220.             check_marker;
  221.             get_bits15(&data);
  222.             streamInfo[stream_num].PTS |= data << 15;
  223.             check_marker;
  224.             get_bits15(&data);
  225.             streamInfo[stream_num].PTS |= data;
  226.             check_marker;
  227.             packet->PTS_Flag=TRUE;
  228.             
  229.             if( !next_bits(4,1) )
  230.                 return (err | ERR_INVALID_BITS);
  231.             flush_bits(4);
  232.     
  233.             get_bits1(&data);
  234.             streamInfo[stream_num].DTS_hibit = data;
  235.             get_bits2(&data);
  236.             streamInfo[stream_num].DTS = data << 30;
  237.             check_marker;
  238.             get_bits15(&data);
  239.             streamInfo[stream_num].DTS |= data << 15;
  240.             check_marker;
  241.             get_bits15(&data);
  242.             streamInfo[stream_num].DTS |= data;
  243.             check_marker;
  244.             packet->DTS_Flag=TRUE;
  245.             byte_count +=10;
  246.  
  247.         }else{
  248.             if( !next_bits(8,0x0f))
  249.                 return (err | ERR_INVALID_BITS);
  250.             flush_bits(8);
  251.             byte_count++;
  252.         }
  253.      }
  254.  
  255.     /* create a buffer to contain the packet data and copy it in */
  256.     packet->buffer_size = packet->packet_length - byte_count;
  257.  
  258.     packet->buffer = (char *) malloc(packet->buffer_size);
  259.     if(packet->buffer == NULL){
  260.         return (err | ERR_MALLOC);
  261.     }
  262.  
  263.     bptr = packet->buffer;
  264.  
  265.     for( i=0; i < (packet->buffer_size); i++){
  266.         get_bits8(&data);
  267.         *bptr++=(char) data;
  268.     }
  269.  
  270.     return NO_ERROR;
  271. }
  272.  
  273.